iT邦幫忙

2022 iThome 鐵人賽

DAY 19
0
自我挑戰組

新手前端與真實世界的開發 feat.React 與他的夥伴系列 第 19

Day-19 專案演練 - 打造表格排序功能 react-table

  • 分享至 

  • xImage
  •  

Day-19 專案演練 - 打造表格排序功能 react-table

表格排序指的是用表格的標題的內容來排序整個表格,雖然可以排序的東西是不限任何型態,只要是長在表格裡的東西都可以做排序,但我決定要多加一行來放時間,這樣排序起來也許會比較帶感(?)

在表格中加入時間

在寫 list 的時候,其實有把時間寫上去,但並沒有放上去表格 :

const [list, setList] =
  useState <any>
  (() => [
    { time: "2018-07-22", title: "購物", info: "日用品", checked: false },
    { time: "2022-09-15", title: "鐵人賽", info: "day-10", checked: true },
    { time: "2022-09-25", title: "摺棉被", info: "", checked: false },
  ]);

接下來要讓表格顯示時間,也很簡單,我們的表格資料都已經交給 react-table 了,所以只要更新 columns 就行了!

const columns = useMemo(
  () => [
    {
      id: "select",
      header: ({ table }) => (
        <IndeterminateCheckbox
          className="form-input border-[2px] rounded border-gray-300 w-[20px] h-[20px]"
          {...{
            checked: table.getIsAllRowsSelected(),
            indeterminate: table.getIsSomeRowsSelected(),
            onChange: table.getToggleAllRowsSelectedHandler(),
          }}
        />
      ),
      cell: ({ row }) => (
        <div className="px-1">
          <IndeterminateCheckbox
            className="form-input border-[2px] rounded border-gray-300 w-[20px] h-[20px]"
            {...{
              checked: row.getIsSelected(),
              indeterminate: row.getIsSomeSelected(),
              onChange: row.getToggleSelectedHandler(),
            }}
          />
        </div>
      ),
    },
    { header: "時間", accessorKey: "time" }, // 這邊
    { header: "任務標題", accessorKey: "title" },
    { header: "詳情", accessorKey: "info" },
  ],
  []
);

這時候應該可以看到表格出現時間資料了!

引入必要的工具

接下來把 react-table 排序的必要工具引進來 :

import {
  useReactTable,
  getCoreRowModel,
  flexRender,
  getSortedRowModel, // 這個
  SortingState, // 與它的型別檔案一起
} from "@tanstack/react-table";

安裝排序功能

首先,新增一個 state,是給排序使用的 :

const [sorting, setSorting] = React.useState < SortingState > [];

之後,將它交給 useTable :

const table = useReactTable({
  data,
  columns,
  state: {
    rowSelection,
    sorting, // 這裡
  },
  onSortingChange: setSorting, // 別忘了要 setSorting
  onRowSelectionChange: setRowSelection,
  getCoreRowModel: getCoreRowModel(),
  getSortedRowModel: getSortedRowModel(),
});

最後一步,在表格讓 table 幫你 sort,是的,只需要更新表頭的部分 :

...
 <Thead>
              {table.getHeaderGroups().map((headerGroup) => (
                <Tr>
                  {headerGroup.headers.map((header) => (
                    <Th
                      {...{
                        className: header.column.getCanSort() // getCanSort()
                          ? "cursor-pointer select-none"
                          : "",
                        onClick: header.column.getToggleSortingHandler(), // getToggleSortingHandler() 
                      }}
                    >
                      {header.isPlaceholder
                        ? null
                        : flexRender(
                            header.column.columnDef.header,
                            header.getContext()
                          )}
                      {{
                        asc: " ?",
                        desc: " ?",// 最後是圖示的部分
                      }[header.column.getIsSorted() as string] ?? null} 
                    </Th>
                  ))}
                </Tr>
              ))}
            </Thead>
            ...

插曲

找範例時不小心跑去 svelte examples,看到的時候還以為什麼時候程式碼變得那麼奇怪(??)

repo

附上程式碼

  • 勘誤 :commit 是想寫排序不是篩選

結語

學習 react-table 有種倒吃甘蔗的感覺,一開始要設定的內容很多,要適應用 table 來渲染表格也花了不少時間,但學會使用方法後,後面安裝功能卻輕鬆了不少。

感覺寫到這,都有點在偷懶的感覺啊。

參考資料


上一篇
Day-18 專案演練 - 重構程式碼
下一篇
Day-20 專案演練 - 輸出報表 react-csv
系列文
新手前端與真實世界的開發 feat.React 與他的夥伴30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言